package com.hc.tenant.aspect;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SimplePropertyPreFilter;
import com.hc.common.core.constant.CacheConstants;
import com.hc.common.datasource.DynamicSaasDataSource;
import com.hc.common.redis.service.RedisService;
import com.hc.common.security.service.TokenService;
import com.hc.system.api.RemoteUserService;
import com.hc.tenant.domain.Location;
import com.hc.tenant.domain.MqttMsgSend;
import com.hc.tenant.domain.RobotCommand;
import com.hc.tenant.service.ILocationService;
import com.hc.tenant.service.IMqttMsgSendService;
import com.hc.tenant.service.IRobotCommandService;
import com.hc.tenant.service.IRobotSettingService;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Collection;
import java.util.Date;
import java.util.List;

@Aspect
@Component
public class tenantAspect {
    @Autowired
    private IMqttMsgSendService mqttMsgSendService;
    @Autowired
    private TokenService tokenService;
    @Autowired
    private IRobotCommandService robotCommandService;
    @Autowired
    private ILocationService locationService;
    @Autowired
    private RedisService redisService;
    @Autowired
    private RemoteUserService remoteUserService;
    @Autowired
    private IRobotSettingService robotSettingService;

    private static final Logger log = LoggerFactory.getLogger(tenantAspect.class);

    @AfterReturning(value = "execution( public * com.hc.tenant.service.IRobotCommandService.insert*(..)) " +
            "|| execution( public * com.hc.tenant.service.IRobotCommandService.update*(..))"+
            "|| execution( public * com.hc.tenant.service.IRobotCommandService.delete*(..))",returning = "count")
    public void commandChange(int count){
        if(count > 0) {
            List<String> tokens = getTokens();
            List<RobotCommand> list = robotCommandService.selectRobotCommandList(new RobotCommand());
            SimplePropertyPreFilter filter = new SimplePropertyPreFilter("commandType", "commandName", "requestText","responseText","location"
                    ,"locationId","locationName","orientation","xAxes","yAxes");
            String json = JSON.toJSONString(list, filter);
            for(String token : tokens){
                MqttMsgSend mqttMsgSend = new MqttMsgSend();
                mqttMsgSend.setCreateTime(new Date());
                mqttMsgSend.setMsg(json);
                mqttMsgSend.setTopicName("saas/commandChange/"+token);
                mqttMsgSendService.insertMqttMsgSend(mqttMsgSend);

            }
        }
    }



    @AfterReturning(value = "execution( public * com.hc.tenant.service.ILocationService.insert*(..)) " +
            "|| execution( public * com.hc.tenant.service.ILocationService.update*(..))"+
            "|| execution( public * com.hc.tenant.service.ILocationService.delete*(..))",returning = "count")
    public void locationChange(int count){
        if(count > 0) {
            List<String> tokens = getTokens();
            List<Location> list = locationService.selectLocationList(new Location());

            SimplePropertyPreFilter filter = new SimplePropertyPreFilter("locationId", "locationName", "xAxes","yAxes","orientation");
            String json = JSON.toJSONString(list, filter);

            for(String token : tokens){
                MqttMsgSend mqttMsgSend = new MqttMsgSend();
                mqttMsgSend.setCreateTime(new Date());
                mqttMsgSend.setMsg(json);
                mqttMsgSend.setTopicName("saas/locationChange/"+token);
                mqttMsgSendService.insertMqttMsgSend(mqttMsgSend);

            }
        }
    }


//    @AfterReturning(value = "execution( public * com.hc.tenant.service.IRobotSettingService.insert*(..)) " +
//            "|| execution( public * com.hc.tenant.service.IRobotSettingService.update*(..))"+
//            "|| execution( public * com.hc.tenant.service.IRobotSettingService.delete*(..))",returning = "count")
//    public void robotSettingChange(int count){
//        if(count > 0) {
//            List<String> tokens = getTokens();
//            List<RobotSetting> list = robotSettingService.selectRobotSettingList(new RobotSetting());
//            ObjectMapper mapper = new ObjectMapper();
//            mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
//            String json = "";
//            try {
//                json = mapper.writeValueAsString(list);
//            } catch (JsonProcessingException e) {
//                log.error("异常信息:{}", e.getMessage());
//            }
//            for(String token : tokens){
//                MqttMsgSend mqttMsgSend = new MqttMsgSend();
//                mqttMsgSend.setCreateTime(new Date());
//                mqttMsgSend.setMsg(json);
//                mqttMsgSend.setTopicName("saas/robotSettingChange/"+token);
//                mqttMsgSendService.insertMqttMsgSend(mqttMsgSend);
//            }
//        }
//    }


   @Around(value = "execution(public * com.hc.tenant.config.ScheduleConfig.mqttPublish(..))")
    public void mqttMsgSend(ProceedingJoinPoint joinPoint) throws Throwable {
        List<String> datasourceNames = remoteUserService.listDatasourceName();
        for(String dataSourceName : datasourceNames){
            DynamicSaasDataSource.setDataSource(dataSourceName);
            joinPoint.proceed();
        }
        DynamicSaasDataSource.clearDataSource();
        return;
    }

    private List<String> getTokens(){
        String dataSourceName = tokenService.getLoginUser().getDataSourceName();
        String key = CacheConstants.LOGIN_DATASOURCE + dataSourceName +  CacheConstants.DATASOURCE_SPLIT + '*';
        Collection<String> keys =redisService.keys(key);
        List<String> tokens = redisService.getMultiCacheValue(keys);
        return tokens;
    }
}
